package com.cssy.xxkj.logic.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.byd.acegiext.domain.User;
import com.cssy.xxkj.logic.contants.BillStatusUtil;
import com.cssy.xxkj.logic.contants.BillTypeConstant;
import com.cssy.xxkj.logic.dao.LogicCheckBackDAO;
import com.cssy.xxkj.logic.dao.LogicCheckBackItemDAO;
import com.cssy.xxkj.logic.dao.LogicProductionStorageoutItemDAO;
import com.cssy.xxkj.logic.entity.LogicCheckBackDO;
import com.cssy.xxkj.logic.entity.LogicCheckBackItemDO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageoutDO;
import com.cssy.xxkj.logic.entity.LogicProductionStorageoutItemDO;
import com.cssy.xxkj.logic.entity.LogicWarehouseOtheroutDO;
import com.cssy.xxkj.logic.entity.LogicWarehouseOtheroutItemDO;
import com.cssy.xxkj.logic.entity.vo.LogicCheckBackVo;
import com.cssy.xxkj.logic.service.ILogicCheckBackService;
import com.cssy.xxkj.logic.service.ILogicHsUtilService;
import com.cssy.xxkj.logic.service.ILogicProductionStorageOutService;
import com.cssy.xxkj.logic.service.ILogicWareHouseOtherOutItemService;
import com.cssy.xxkj.logic.service.ILogicWareHouseOtherOutService;
import com.plat.exception.SyBaseException;
import com.plat.helper.SearchCondition;
import com.plat.helper.SearchConditions;
import com.plat.helper.SearchResult;
import com.plat.util.DateUtils;
import com.plat.util.GlobalResLoader;
import com.plat.util.IDCodeTypeUtil;
import com.plat.util.SessionUtil;
import com.yuendong.sy.po.code.SyCode;
import com.yuendong.sy.service.code.impl.SyCodeService;

@Service("logicCheckBackService")
public class LogicCheckBackServiceImpl implements ILogicCheckBackService {
	@Resource(name="logicCheckBackDAO") 
	private LogicCheckBackDAO logicCheckBackDAO;
	
	@Resource(name="logicCheckBackItemDAO")
	private LogicCheckBackItemDAO logicCheckBackItemDAO; 

	@Resource(name = "logicWareHouseOtherOutItemService")
	private ILogicWareHouseOtherOutItemService logicWareHouseOtherOutItemService;
	
	@Resource(name = "syCodeService")
	private SyCodeService syCodeService;
	
	@Resource(name = "logicHsUtilService")
	private ILogicHsUtilService logicHsUtilService ;
	
	@Resource(name="logicWareHouseOtherOutService")
	private ILogicWareHouseOtherOutService logicWareHouseOtherOutService;
	
	@Resource(name="logicProductionStorageOutService")
	private ILogicProductionStorageOutService logicProductionStorageOutService;
	
	@Resource(name="logicProductionStorageoutItemDAO")
	private LogicProductionStorageoutItemDAO logicProductionStorageoutItemDAO;
	
	
	@Override
	public SearchResult findListByExample(SearchConditions scs)
			throws SyBaseException {
		SearchResult rs = new SearchResult(scs);
		List<LogicCheckBackDO> list = logicCheckBackDAO.find(scs);
		rs.setRecordCount(logicCheckBackDAO.count(scs));
		rs.setResults(list);
		return rs;
	}

	@Override
	public Integer delete(String id, User user) throws SyBaseException {
		LogicCheckBackDO ld= new LogicCheckBackDO();
		ld.setId(id);
		ld.setRemoved(1l);//删除
		return logicCheckBackDAO.updateLogicCheckBackDO(ld);
		
	}

	@Override
	public Integer update(LogicCheckBackDO t, User user) throws SyBaseException {
		t.setBizModifyDate(new Date());
		t.setBizModifyName(user.getName());
		t.setBizVersionMark(t.getBizVersion());
		t.setBizVersion(t.getBizVersion()+1);
		return logicCheckBackDAO.updateLogicCheckBackDO(t);
	}

	@Override
	public LogicCheckBackDO save(LogicCheckBackDO t, User user)
			throws SyBaseException {
		t.setBizCreatorDate(new Date());
		t.setBizCreatorName(user.getName());
		t.setBizVersion(Integer.valueOf(1));
		logicCheckBackDAO.insertLogicCheckBackDO(t);
		return null;
	}

	@Override
	public LogicCheckBackDO findListById(String id) throws SyBaseException {
		return logicCheckBackDAO.findLogicCheckBackDOByPrimaryKey(id);
	}

	@Override
	public Integer deleteBizRemoved(String id) throws SyBaseException {
		
		return logicCheckBackDAO.deleteBizRemoved(id);
	}

	@Override
	public void cbSave(LogicCheckBackDO curAP, HttpServletRequest request)
			throws SyBaseException {
		try {
			String checkDate = request.getParameter("zd009Date");
			if(StringUtils.isBlank(checkDate)||checkDate==null){
				curAP.setZd009Date(new Date());
			}else{
				curAP.setZd009Date(DateUtils.stringToDate(checkDate));
			}
			//获取行记录
			String json = request.getParameter("addressInfos");
			List<LogicCheckBackItemDO> checkItemList=JSONArray.parseArray(json, LogicCheckBackItemDO.class);
			if(curAP==null || StringUtils.isBlank(curAP.getId())){
				//新增
				String checkId = IDCodeTypeUtil.getId();
				curAP.setId(checkId);
				String checkCode = syCodeService.getCode(BillTypeConstant.CHECKBACK,BillTypeConstant.CHECKBACK,SyCode.DATE_YYMM,5);
				curAP.setZd001CheckCode(checkCode);
				this.save(curAP, SessionUtil.getUser(request));
				//保存反审行记录
				for(LogicCheckBackItemDO checkItem : checkItemList){
					if(checkItem==null){
						continue;
					}
					checkItem.setId(IDCodeTypeUtil.getId());
					checkItem.setZd001CkeckBackId(checkId);
					checkItem.setZd001CheckBackCode(checkCode);
					this.logicCheckBackItemDAO.insertLogicCheckBackItemDO(checkItem);
				}
			}else{
				//修改
				this.logicCheckBackItemDAO.deleteLogicCheckBackItemDOByLogicCheckBackId(curAP.getId());
				//判断是否审核通过
				if(BillStatusUtil.CHECK_BACK_THREE.equals(curAP.getZd011Stauts())){
					LogicCheckBackDO backEntity = this.logicCheckBackDAO.findLogicCheckBackDOByPrimaryKey(curAP.getId());
					if(backEntity==null){
						throw new SyBaseException("修改的数据已发生改变，请重新提交.");
					}
					//审核通过，且修改库存
					//组装成map对象，避免N+1查询  反审表中所有本张单的数据
					Map<String, BigDecimal> hsBackMap = this.findQueryHsBackItemToMap(backEntity.getZd002BackId());
					//获得要反审的对象所有行记录的数据
					Map<String, Object> itemMap=this.findQuanryOutItemToMap(curAP.getZd002BackId(),curAP.getZd008Type());
					for(LogicCheckBackItemDO checkItem : checkItemList){
						if(checkItem==null || StringUtils.isBlank(checkItem.getId())){
							continue;
						}
						// 总数量
						BigDecimal sumQuantity = checkItem.getZd020WareOutQuanlity()==null?BigDecimal.ZERO:checkItem.getZd020WareOutQuanlity();
						//当期数量
						BigDecimal theQuantity = checkItem.getZd023BackQuanlity()==null?BigDecimal.ZERO:checkItem.getZd023BackQuanlity();
						BigDecimal canQuantity = BigDecimal.ZERO;
						//判断反审类型
						//key 反审主记录id+货物编码+型号+规格+颜色+材质
						String keyStr = curAP.getZd002BackId()+"_"+checkItem.getZd003MaterialsCode()+"_"
								+checkItem.getZd006MaterialsModel()+"_"+checkItem.getZd005MaterialsSpec()+"_"
								+checkItem.getZd017MaterialsColor()+"_"+checkItem.getZd018MaterialsQuality();
						if(hsBackMap==null||hsBackMap.get(keyStr)==null){
							canQuantity = theQuantity;
						}else{
							canQuantity = theQuantity.add(hsBackMap.get(keyStr));
						}
						int backUp = sumQuantity.subtract(canQuantity).compareTo(BigDecimal.ZERO);
						if(backUp==-1){
							throw new SyBaseException("物料："+checkItem.getZd004MaterialsName()+"反审总数量已大于出库数量!");
						}
						//插入反审行记录信息
						this.logicCheckBackItemDAO.insertLogicCheckBackItemDO(checkItem);
						//判断反审类型
						if(BillStatusUtil.CHECK_BACK_OTHEROUT.equals(curAP.getZd008Type())){
							//修改反审行记录的已反审的数量字段的值
							LogicWarehouseOtheroutItemDO outItem = (LogicWarehouseOtheroutItemDO) itemMap.get(keyStr);
							if(outItem==null){
								throw new SyBaseException("数据以修改，反审失败！！！");
							}else{
								BigDecimal antiQuantity = outItem.getZd015AntiTrialQuantity()==null?BigDecimal.ZERO:outItem.getZd015AntiTrialQuantity();
								outItem.setZd015AntiTrialQuantity(antiQuantity.add(theQuantity));
								this.logicWareHouseOtherOutItemService.update(outItem, SessionUtil.getUser(request));
							}
						}else if(BillStatusUtil.CHECK_BACK_SALESOUT.equals(curAP.getZd008Type())){
							LogicProductionStorageoutItemDO outItem=(LogicProductionStorageoutItemDO) itemMap.get(keyStr);
							if(outItem==null){
								throw new SyBaseException("数据以修改，反审失败");
							}else{
								//LogicProductionStorageoutItemDO 跟新反审总数
								BigDecimal antiQuantity=outItem.getZd022AntiTrialQuantity()==null?BigDecimal.ZERO:outItem.getZd022AntiTrialQuantity();
								outItem.setZd022AntiTrialQuantity(antiQuantity.add(theQuantity));
								this.logicProductionStorageoutItemDAO.updateLogicProductionStorageoutItemDO(outItem);
							}
						}
						//修改库存
						logicHsUtilService.processCheckBack(backEntity, checkItem, SessionUtil.getUser(request));
					}
					backEntity.setZd011Stauts(BillStatusUtil.CHECK_BACK_THREE);
					Integer upRow = this.update(backEntity, SessionUtil.getUser(request));
					if(upRow==null||upRow.intValue()==0){
						throw new SyBaseException("修改的数据已发生改变，请重新提交.");
					}
				}else{
					Integer upRow = this.update(curAP, SessionUtil.getUser(request));
					//对航记录的操作
					if(upRow==null||upRow.intValue()==0){
						throw new SyBaseException("修改的数据已发生改变，请重新提交.");
					}
					for(LogicCheckBackItemDO checkItem : checkItemList){
						if(checkItem==null){
							continue;
						}
						checkItem.setId(IDCodeTypeUtil.getId());
						checkItem.setZd001CkeckBackId(curAP.getId());
						checkItem.setZd001CheckBackCode(curAP.getZd001CheckCode());
						this.logicCheckBackItemDAO.insertLogicCheckBackItemDO(checkItem);
					}
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new SyBaseException(GlobalResLoader.getOpfailed() + e.getMessage());
		}
		
	}

	
	private Map<String, Object> findQuanryOutItemToMap(String checkBackId,String type){
		SearchConditions outItemScs = new SearchConditions();
		outItemScs.setRemovedProperty(null);  //删除所有没有不是删除状态的数据
		Map<String, Object> itemMap = new HashMap<String, Object>();
		if(BillStatusUtil.CHECK_BACK_OTHEROUT.equals(type)){
			outItemScs.addCondition("zd001OtherOutId",checkBackId,SearchCondition.OP_EQUAL);
			List<LogicWarehouseOtheroutItemDO> outItemList = this.logicWareHouseOtherOutItemService.findListByExample(outItemScs).getResults();
			if(outItemList!=null&&!outItemList.isEmpty()&&outItemList.size()>0){
				for(LogicWarehouseOtheroutItemDO outItem : outItemList){
					if(outItem==null||StringUtils.isBlank(outItem.getId())){
						continue;
					}
					//key 反审主记录id+货物编码+型号+规格+颜色+材质
					String keyStr = checkBackId+"_"+outItem.getZd002MaterialsCode()+"_"
						+outItem.getZd004MaterialsModel()+"_"+outItem.getZd003MaterialsSpec()+"_"
						+outItem.getZd016MaterialsColor()+"_"+outItem.getZd017MaterialsQuanlity();
					itemMap.put(keyStr, outItem);
				}
			}
		}else if(BillStatusUtil.CHECK_BACK_SALESOUT.equals(type)){
			outItemScs.addCondition("zd001OtherOutId",checkBackId,SearchCondition.OP_EQUAL);
			List<LogicProductionStorageoutItemDO> outItemList= this.logicProductionStorageOutService.findStorOutItemList(checkBackId);
			if(outItemList!=null&&!outItemList.isEmpty()&&outItemList.size()>0){
				for( LogicProductionStorageoutItemDO outItem:outItemList ){
					 if(outItem==null||StringUtils.isBlank(outItem.getId())){
						 continue;
					 }
					 //组装map key 为判断物品的哪些条件 反审主记录id+货物编码+型号+规格+颜色+材质
					 String keyStr= checkBackId+"_"+outItem.getZd002MaterialsCode()+"_"
							 +outItem.getZd004MaterialsModel()+"_"+outItem.getZd016MaterialsSize()+"_"//销售出库中size是规格
							 +outItem.getZd017MaterialsColor()+"_"+outItem.getZd018MaterialsQuality();
					 itemMap.put(keyStr, outItem);
				}
			}
		}
		return itemMap;
	}
	
	private Map<String, BigDecimal> findQueryHsBackItemToMap(String checkBackId){
		Map<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("backId", checkBackId);
		paramMap.put("billSt", BillStatusUtil.CHECK_BACK_THREE);
		
		List<LogicCheckBackItemDO> backItemList = logicCheckBackItemDAO.findListByMap(paramMap);
		if(backItemList==null||backItemList.isEmpty()||backItemList.size()==0){
			return null;
		}else{
			Map<String, BigDecimal> backMap = new HashMap<String, BigDecimal>();
			for(LogicCheckBackItemDO backItem : backItemList){
				if(backItem==null||StringUtils.isBlank(backItem.getId())){
					continue;
				}//key 反审主记录id+货物编码+型号+规格+颜色+材质
				String keyStr = paramMap.get("backId")+"_"+backItem.getZd003MaterialsCode()+"_"
					+backItem.getZd006MaterialsModel()+"_"+backItem.getZd005MaterialsSpec()+"_"
					+backItem.getZd017MaterialsColor()+"_"+backItem.getZd018MaterialsQuality();
				BigDecimal backQuantity = backItem.getZd023BackQuanlity()==null?BigDecimal.ZERO:backItem.getZd023BackQuanlity();
				if(backMap.get(keyStr)==null){
					backMap.put(keyStr, backQuantity);
				}else{
					backMap.put(keyStr, backQuantity.add(backMap.get(keyStr)));
				}
			}
			return backMap;
		}
	}

	@Override
	public List<LogicCheckBackItemDO> getCheckBackItemList(String id,String type) throws SyBaseException {
		List<LogicCheckBackItemDO> backItemList= new ArrayList<LogicCheckBackItemDO>();
		//其他出库单
		if(BillStatusUtil.CHECK_BACK_OTHEROUT.equals(type)){
			List<LogicWarehouseOtheroutItemDO> outItemList=logicWareHouseOtherOutItemService.findByPid(id);
			if(outItemList!=null&&!outItemList.isEmpty()&&outItemList.size()>0){
				for(LogicWarehouseOtheroutItemDO outItem : outItemList){
					if(outItem==null||StringUtils.isBlank(outItem.getId())){
						continue;
					}
					backItemList.add(this.getCheckBackItemByLogicWarehouseOtheroutItemDO(outItem));
				}
			}
		}
		//销售出库单
		if(BillStatusUtil.CHECK_BACK_SALESOUT.equals(type)){
			LogicProductionStorageoutDO stgOut = logicProductionStorageOutService.findListById(id);
			List<LogicProductionStorageoutItemDO> list=logicProductionStorageOutService.findStorOutItemList(id);
			if(list!=null&&!list.isEmpty()&&list.size()>0){
				for(LogicProductionStorageoutItemDO ld:list){
					if(ld==null||StringUtils.isBlank(ld.getId())){
						continue;
					}
					LogicCheckBackItemDO lc = this.getLogicCheckBackItemDOByLogicProductionStorageoutItemDO(ld);
					lc.setZd025PiCode(stgOut.getZd003PiCode());
					backItemList.add(lc);
				}
			}
		}
		return backItemList;
	}
	private LogicCheckBackItemDO getLogicCheckBackItemDOByLogicProductionStorageoutItemDO(
			LogicProductionStorageoutItemDO ld){
		LogicCheckBackItemDO lc= new LogicCheckBackItemDO();
		lc.setZd002MaterialsId(ld.getZd002MaterialsId());//id
		//key 反审主记录id+货物编码+型号+规格+颜色+材质
		lc.setZd003MaterialsCode(ld.getZd002MaterialsCode());//编码
		lc.setZd006MaterialsModel(ld.getZd004MaterialsModel());//型号
		lc.setZd005MaterialsSpec(ld.getZd016MaterialsSize());//规格
		lc.setZd017MaterialsColor(ld.getZd017MaterialsColor());//颜色
		lc.setZd018MaterialsQuality(ld.getZd018MaterialsQuality());//材质

		lc.setZd004MaterialsName(ld.getZd002MaterialsName());//名称
		lc.setZd007MaterialsBrand(ld.getZd005MaterialsBrand());
		lc.setZd008Status(ld.getZd008Status());
		lc.setZd008Unit(ld.getZd006Unit());
		lc.setZd009Price(ld.getZd009Price());
		lc.setZd010Batch(ld.getZd010Batch());
		lc.setZd019WhQuanlity(ld.getZd019WhQuanlity());//库存
		lc.setZd020WareOutQuanlity(ld.getZd007Quantity());//已出库数
		lc.setZd021OutQuanlity(ld.getZd020WareOutQuanlity());//订单数量
		
		BigDecimal hsQuantity = ld.getZd022AntiTrialQuantity()==null?BigDecimal.ZERO:ld.getZd022AntiTrialQuantity();
		lc.setZd024HsBackQuantity(hsQuantity);
		return lc;
	}
	
	
	private LogicCheckBackItemDO getCheckBackItemByLogicWarehouseOtheroutItemDO(LogicWarehouseOtheroutItemDO outItem){
		LogicCheckBackItemDO lc=new LogicCheckBackItemDO();
		lc.setZd002MaterialsId(outItem.getZd002MaterialsId());//id
		//key 反审主记录id+货物编码+型号+规格+颜色+材质
		lc.setZd003MaterialsCode(outItem.getZd002MaterialsCode());//编码
		lc.setZd006MaterialsModel(outItem.getZd004MaterialsModel());//型号
		lc.setZd005MaterialsSpec(outItem.getZd003MaterialsSpec());//规格
		lc.setZd017MaterialsColor(outItem.getZd016MaterialsColor());//颜色
		lc.setZd018MaterialsQuality(outItem.getZd017MaterialsQuanlity());//材质
		lc.setZd004MaterialsName(outItem.getZd002MaterialsName());//名称
		lc.setZd007MaterialsBrand(outItem.getZd005MaterialsBrand());
		lc.setZd008Status(outItem.getZd008Status());
		lc.setZd008Unit(outItem.getZd006Unit());
		lc.setZd009Price(outItem.getZd009Price());
		lc.setZd010Batch(outItem.getZd010Batch());
		lc.setZd019WhQuanlity(outItem.getZd014WhQuantity());//库存
		lc.setZd020WareOutQuanlity(outItem.getZd007Quantity());
		lc.setZd025PiCode(outItem.getZd018PiCode());
		
		BigDecimal hsQuantity = outItem.getZd015AntiTrialQuantity()==null?BigDecimal.ZERO:outItem.getZd015AntiTrialQuantity();
		lc.setZd024HsBackQuantity(hsQuantity);
		return lc;
	}
	
	//把LogicWareHouseOtherOut转变为 LogicCheckBackVo 其他出库主表对象转变为vo对象
	public List<LogicCheckBackVo> getCheckBackVoForLogicWareHouseOtherOut(SearchConditions scs)
			throws SyBaseException{
		List<LogicCheckBackVo> lv= new ArrayList<LogicCheckBackVo>();
		List<LogicWarehouseOtheroutDO> ld=logicWareHouseOtherOutService.findListByExample(scs).getResults();
		for(LogicWarehouseOtheroutDO lw:ld){
			LogicCheckBackVo lc= new LogicCheckBackVo();
			lc.setZd001CheckCode(lw.getZd002OriCode());// 原始单号（X）
			lc.setZd002BackCode(lw.getZd001OutCode());//反审对象单号
			lc.setZd002BackId(lw.getId());//反审对象Id
			lc.setZd003PiCode(lw.getZd005Batch());// PI单号
			lc.setZd004WhCode(lw.getZd004WhCode());// 仓库编码
			lc.setZd004Whid(lw.getZd004Whid());//仓库ID
			lc.setZd004WhName(lw.getZd004WhName());//仓库名称
			lc.setZd007CustomerCode(lw.getZd011CustomerCode());//客户编码
			lc.setZd007CustomerId(lw.getZd011CustomerID());//客户ID
			lc.setZd007CustomerName(lw.getZd011CustomerName());//客户名称
			lc.setZd009Date(lw.getZd010OtherDate());//出库日期
			lc.setZd006Aegnt(lw.getZd006Aegnt());//反审对象经办人
			lv.add(lc);
		}
		return lv;
	}

	@Override
	public List<LogicCheckBackVo> getCheckBackVoForLogicProductionStorageoutDO(
			SearchConditions scs) throws SyBaseException {
		List<LogicCheckBackVo> lv= new ArrayList<LogicCheckBackVo>();
		List<LogicProductionStorageoutDO> prolist=logicProductionStorageOutService.findListByExample(scs).getResults();
		for(LogicProductionStorageoutDO lw:prolist){
			LogicCheckBackVo lc= new LogicCheckBackVo();
			lc.setZd001CheckCode(lw.getZd002OriCode());// 原始单号（X）
			lc.setZd002BackCode(lw.getZd001OutCode());//反审对象单号
			lc.setZd002BackId(lw.getId());//反审对象Id
			lc.setZd003PiCode(lw.getZd003PiCode());// PI单号
			lc.setZd004WhCode(lw.getZd004WhCode());// 仓库编码
			lc.setZd004Whid(lw.getZd004WhId());//仓库ID
			lc.setZd004WhName(lw.getZd004WhName());//仓库名称
			lc.setZd007CustomerCode(lw.getZd012CustomerCode());//客户编码
			lc.setZd007CustomerId(lw.getZd012CustomerId());//客户ID
			lc.setZd007CustomerName(lw.getZd012CustomerName());//客户名称
			lc.setZd009Date(lw.getZd010OtherDate());//出库日期
			lc.setZd006Aegnt(lw.getZd006Aegnt());//反审对象经办人
			lv.add(lc);
		}
		return lv;
	}

}
